package com.butnet.myframe.template.impl;

import java.io.File;
import java.io.FileReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.Reader;
import java.util.LinkedList;
import java.util.List;

import com.butnet.myframe.template.TemplateLexer;
import com.butnet.myframe.template.TemplateLexerListener;

public class TemplateLexerImpl implements TemplateLexer {
	public static String newLine = System.getProperty("line.separator");
	@Override
	public void parse(InputStream in) {
		init();
		Reader reader = null;
		try {
			int num;
			char[] buff = new char[1024];
			reader = new InputStreamReader(in);
			while ((num = reader.read(buff)) != -1) {
				doChars(buff, 0, num);
			}
		} catch (IOException e) {
			e.printStackTrace();
		} finally {
			if (reader != null) {
				try {
					endWord();
					reader.close();
				} catch (IOException ex) {
					ex.printStackTrace();
				}
			}
		}
	}
	@Override
	public void parse(File file) {
		init();
		FileReader reader = null;
		try {
			int num;
			char[] buff = new char[1024];
			reader = new FileReader(file);
			while ((num = reader.read(buff)) != -1) {
				doChars(buff, 0, num);
			}
		} catch (IOException e) {
			e.printStackTrace();
		} finally {
			if (reader != null) {
				try {
					endWord();
					reader.close();
				} catch (IOException ex) {
					ex.printStackTrace();
				}
			}
		}
	}

	@Override
	public String next() {
		if (words_index < words.size())
			return words.get(words_index++);
		return null;
	}

	@Override
	public boolean hasNext() {
		if (words.size() > 0 && words_index < words.size())
			return true;
		return false;
	}

	@Override
	public String getAt(int index) {
		if (index >= 0 && index < words.size() && words.size() > 0) {
			words_index = index;
			return next();
		}
		return null;
	}

	@Override
	public int size() {
		return words.size();
	}

	@Override
	public void addTemplateLexerListener(TemplateLexerListener listener) {
		if(listener!=null)
			listeners.add(listener);
	}

	@Override
	public void removeTemplateLexerListener(TemplateLexerListener listener) {
		listeners.remove(listener);
	}

	/**
	 * 处理字符
	 * 
	 * @param chars
	 *            需要处理的字符
	 * @param len
	 * @param off
	 */
	private void doChars(char[] chars, int off, int len) {
		for (int i = off; i < len; i++) {
			if (isExpressionStart) {
				addWord(chars[i]);
				previousChar = chars[i];
			} else {
				if (previousChar == null) {
					if (chars[i] == '#') {
						previousChar = chars[i];
						isExpressionStart = true;
						continue;
					} else {
						isExpressionStart = false;
					}
				} else if (!previousChar.equals('\\')) {
					if (chars[i] == '#') {
						previousChar = chars[i];
						isExpressionStart = true;
						continue;
					} else {
						isExpressionStart = false;
					}
				} else {
					if (chars[i] == '#') {
						currentContentString.delete(currentContentString.length()-1, currentContentString.length());// \#时，转义#
					}
					isExpressionStart = false;
				}
				addWord(chars[i]);
				previousChar = chars[i];
			}
		}
	}

	/**
	 * 语句分析
	 * 
	 * @param c
	 */
	private void addWord(char c) {
		if (isExpressionStart) {
			if (currentContentString.length() != 0) {
				fireListeners(currentContentString.toString(), TemplateLexerListener.ContentType.TEXT);
				words.add("t:" + currentContentString.toString());
				currentContentString.delete(0, currentContentString.length());
			}
			if (c != '#' && c != '\r' && c != '\n')
				currentExpressionString.append(c);
			else if (c == '#' && !previousChar.equals('\\')) {
				fireListeners(currentExpressionString.toString(), TemplateLexerListener.ContentType.EXPRESSION);
				words.add("e:" + currentExpressionString.toString());
				currentExpressionString.delete(0, currentExpressionString
						.length());
				isExpressionStart = false;
			} else if (c == '#' && previousChar.equals('\\')) {
				currentExpressionString.append(c);
			} else {
				fireListeners(currentExpressionString.toString(), TemplateLexerListener.ContentType.EXPRESSION);
				words.add("e:" + currentExpressionString.toString());
				currentExpressionString.delete(0, currentExpressionString
						.length());
				isExpressionStart = false;
			}
		} else {
			if (currentExpressionString.length() != 0) {
				fireListeners(currentExpressionString.toString(), TemplateLexerListener.ContentType.EXPRESSION);
				words.add("e:" + currentExpressionString.toString());
				currentExpressionString.delete(0, currentExpressionString
						.length());
			}
			if(!(c=='\n'&&'\r'==previousChar))
				currentContentString.append(c);
			else{
				if(currentContentString.length()>0&&currentContentString.charAt(currentContentString.length()-1)=='\r'){
					currentContentString.replace(currentContentString.length()-1, currentContentString.length(), newLine);
//					currentContentString.deleteCharAt(currentContentString.length()-1);
//					currentContentString.append(newLine);
				}
			}
		}
	}

	private void endWord() {
		if (isExpressionStart) {
			if (currentExpressionString.length() != 0) {
				fireListeners(currentExpressionString.toString(), TemplateLexerListener.ContentType.EXPRESSION);
				words.add("e:" + currentExpressionString.toString());
				currentExpressionString.delete(0, currentExpressionString
						.length());
			}
		} else {
			if (currentContentString.length() != 0) {
				fireListeners(currentContentString.toString(), TemplateLexerListener.ContentType.TEXT);
				words.add("t:" + currentContentString.toString());
				currentContentString.delete(0, currentContentString.length());
			}
		}
	}

	private void init() {
		words_index = 0;
		isExpressionStart = false;
		previousChar = null;
		words.clear();
		currentContentString.delete(0, currentContentString.length());
		currentExpressionString.delete(0, currentExpressionString.length());
	}
	
	private void fireListeners(String content, TemplateLexerListener.ContentType type){
		for(TemplateLexerListener l : listeners)
			l.append(content, type);
	}

	/**
	 * 索引
	 */
	private int words_index = 0;
	/**
	 * 上一个字符
	 */
	private Character previousChar = null;
	/**
	 * 文件划分为单词
	 */
	private List<String> words = new LinkedList<String>();
	/**
	 * 表达式是否开始
	 */
	private boolean isExpressionStart = false;
	/**
	 * 当前表达式内容
	 */
	private StringBuffer currentExpressionString = new StringBuffer();
	/***
	 * 当前模板内容
	 */
	private StringBuffer currentContentString = new StringBuffer();
	/**
	 * 监听器
	 */
	private List<TemplateLexerListener> listeners = new LinkedList<TemplateLexerListener>();
}
